<!DOCTYPE html>
<html lang="zh-CN">
<html>
<head>
    <meta charset="UTF-8">
    <title>网页采集工具</title>
    <!-- 引入jquery -->
    <script src="../../node_modules/jquery/dist/jquery.min.js"></script>
    <!-- 引入layui -->
    <link href="../../node_modules/layui/dist/css/layui.css" rel="stylesheet">
    <script src="../../node_modules/layui/dist/layui.js"></script>
    <style>
        /* 禁止所有元素的文本选中 */
        * {
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
        }

        body,
        html {
            margin: 0;
            padding: 0;
            height: 100vh;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            font-family: Arial, sans-serif;
            min-width: 800px;
            background-color: #f5f7fa;
        }

        /* 顶部导航栏 */
        .top-nav {
            min-height: 40px;
            padding: 0 10px;
            background: #ffffff;
            display: flex;
            align-items: center;
            border-bottom: 1px solid rgba(0, 0, 0, 0.08);
            gap: 10px;
            flex-wrap: wrap;
            box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02),
            0 2px 4px rgba(0, 0, 0, 0.03),
            0 4px 8px rgba(0, 0, 0, 0.04);
            backdrop-filter: blur(8px);
            position: relative;
            z-index: 100;

        }

        .nav-controls {
            display: flex;
            gap: 5px;
            margin-right: 5px;
            min-width: max-content;
        }

        .nav-icon {
            width: clamp(28px, 3vw, 32px);
            height: clamp(28px, 3vw, 32px);
            border: none;
            background: transparent;
            border-radius: 4px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #666;
            transition: all 0.15s ease-in-out;
            position: relative;
            overflow: hidden;
        }

        .nav-icon:hover {
            background: #f0f0f0;
            color: #333;
            transform: scale(1.1);
        }

        .nav-icon:active {
            transform: scale(0.95);
            background: #e8e8e8;
        }

        .nav-icon::after {
            content: '';
            position: absolute;
            width: 100%;
            height: 100%;
            background: rgba(78, 110, 242, 0.2);
            border-radius: 50%;
            transform: scale(0);
            opacity: 0;
            transition: all 0.2s ease-out;
        }

        .nav-icon:active::after {
            transform: scale(1);
            opacity: 1;
            transition: 0s;
        }

        .nav-icon:disabled {
            opacity: 0.5;
            cursor: not-allowed;
            pointer-events: none;
        }

        .nav-icon svg {
            width: 16px;
            height: 16px;
            transition: transform 0.2s ease;
            z-index: 1;
        }

        .nav-icon:active svg {
            transform: scale(0.9);
        }

        .nav-buttons {
            display: flex;
            gap: 5px;
            min-width: max-content;
        }

        .nav-button {
            padding: clamp(6px, 1vw, 8px) clamp(15px, 2vw, 25px);
            border: none;
            border-radius: 2px;
            cursor: pointer;
            font-size: clamp(12px, 1vw, 14px);
            white-space: nowrap;
            transition: all 0.2s ease;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }

        .nav-button:hover {
            transform: translateY(-1px);
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
        }

        .nav-button:active {
            transform: translateY(1px);
            box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
        }

        .detail-btn {
            background: #33b2ff;
            color: white;
        }

        .save-btn {
            background: #00b8a9;
            color: white;
        }

        .capture-btn {
            background: #4e6ef2;
            color: white;
        }

        .exit-btn {
            background: #ffa502;
            color: white;
        }

        .url-input {
            flex: 1;
            min-width: 200px;
            padding: 6px 10px;
            border: 2px solid #eaeaea;
            border-radius: 2px;
            font-size: 14px;
            transition: all 0.2s ease;
        }

        .url-input:focus {
            outline: none;
            border-color: #4e6ef2;
            box-shadow: 0 0 0 3px rgba(78, 110, 242, 0.1);
        }

        /* 主体内容区域 */
        .main-content {
            flex: 1;
            display: flex;
            position: relative;
            min-width: 0;
            overflow: hidden;
        }

        /* webview 容器 */
        .center-content {
            flex: 1;
            display: flex;
            flex-direction: column;
            min-width: 0;
        }

        .webview-container {
            flex: 1;
            position: relative;
        }

        #myWebview {
            width: 100%;
            height: 100%;
            border: none;
        }

        /* 右侧面板 */
        .right-panel {
            flex: 0 0 300px;
            background: #ffffff;
            border-left: 1px solid rgba(0, 0, 0, 0.08);
            position: relative;
            min-width: 200px;
            max-width: 60%;
            box-shadow: -1px 0 2px rgba(0, 0, 0, 0.02),
            -2px 0 4px rgba(0, 0, 0, 0.03),
            -4px 0 8px rgba(0, 0, 0, 0.04);
            backdrop-filter: blur(8px);
            z-index: 50;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }

        /* 流程图容器 */
        .flow-container {
            flex: 1;
            min-height: 0;
            background-color: #f8f9fa;
            background-image: linear-gradient(to right, rgba(128, 128, 128, .1) 1px, transparent 1px),
            linear-gradient(to bottom, rgba(128, 128, 128, .1) 1px, transparent 1px),
            linear-gradient(to right, rgba(128, 128, 128, .05) .5px, transparent .5px),
            linear-gradient(to bottom, rgba(128, 128, 128, .05) .5px, transparent .5px);
            background-size: 20px 20px, 20px 20px, 4px 4px, 4px 4px;
            background-position: -1px -1px;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }

        /* 流程图内容 */
        .flow-content {
            flex: 1;
            min-height: 0;
            overflow-y: auto;
            overflow-x: hidden;
            padding: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        /* 美化滚动条样式（可选） */
        .flow-content::-webkit-scrollbar {
            width: 6px;
        }

        .flow-content::-webkit-scrollbar-track {
            background: transparent;
        }

        .flow-content::-webkit-scrollbar-thumb {
            background-color: rgba(0, 0, 0, 0.1);
            border-radius: 3px;
        }

        .flow-content::-webkit-scrollbar-thumb:hover {
            background-color: rgba(0, 0, 0, 0.2);
        }

        /* 节点配置区域 */
        .node-config {
            flex: 0 0 200px;
            background: #ffffff;
            border-top: 1px solid rgba(0, 0, 0, 0.08);
            box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.02),
            0 -4px 8px rgba(0, 0, 0, 0.04),
            0 -8px 16px rgba(0, 0, 0, 0.06);
            position: relative;
            min-height: 100px;
            z-index: 60;
            display: none;
            flex-direction: column;
            overflow: hidden;
        }

        /* 节点配置区域的拖动条 */
        .node-config-resizer {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 6px;
            background: transparent;
            cursor: ns-resize;
            z-index: 1;
            border-top: 1px solid rgba(0, 0, 0, 0.08);
            border-bottom: 1px solid rgba(0, 0, 0, 0.08);
        }

        .node-config-resizer:hover {
            background: rgba(78, 110, 242, 0.15);
        }

        .node-config-resizer.resizing {
            background: rgba(78, 110, 242, 0.25);
        }

        /* 节点配置内容区域 */
        .node-config-content {
            flex: 1;
            overflow-y: auto;
            padding: 20px;
            color: #333;
        }

        /* 底部面板 */
        .bottom-panel {
            height: clamp(150px, 30vh, 80vh);
            background: #ffffff;
            border-top: 1px solid rgba(0, 0, 0, 0.08);
            position: relative;
            min-height: 100px;
            box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.02),
            0 -2px 4px rgba(0, 0, 0, 0.03),
            0 -4px 8px rgba(0, 0, 0, 0.04);
            backdrop-filter: blur(8px);
            z-index: 50;
            display: flex;
            flex-direction: column;
        }

        /* 底部工具栏 */
        .bottom-toolbar {
            height: 40px;
            padding: 0 16px;
            border-bottom: 1px solid rgba(0, 0, 0, 0.08);
            display: flex;
            align-items: center;
            justify-content: space-between;
            background: linear-gradient(to bottom, #ffffff, #fafafa);
            flex-shrink: 0;
        }

        /* 预览文本 */
        .preview-text {
            font-size: 14px;
            color: #666;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .preview-text strong {
            color: #333;
        }

        /* 工具栏图标容器 */
        .toolbar-icons {
            display: flex;
            gap: 12px;
            align-items: center;
        }

        /* 工具栏图标按钮 */
        .toolbar-icon {
            width: 32px;
            height: 32px;
            border: none;
            background: transparent;
            border-radius: 4px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #666;
            transition: all 0.2s ease;
        }

        .toolbar-icon:hover {
            background: rgba(0, 0, 0, 0.05);
            color: #333;
        }

        .toolbar-icon:active {
            background: rgba(0, 0, 0, 0.08);
            transform: scale(0.95);
        }

        /* 数据内容区域 */
        .bottom-content {
            flex: 1;
            overflow: auto;
            position: relative;
        }

        /* 拖动条样式 */
        .resizer {
            position: absolute;
            z-index: 1000;
            transition: all 0.2s ease;
            touch-action: none;
            background: transparent;
        }

        .resizer-h {
            top: 0;
            left: 0;
            width: clamp(4px, 0.5vw, 6px);
            height: 100%;
            cursor: ew-resize;
            border-right: 1px solid rgba(0, 0, 0, 0.08);
        }

        .resizer-v {
            left: 0;
            top: 0;
            height: 6px;
            width: 100%;
            cursor: ns-resize;
            border-bottom: 1px solid rgba(0, 0, 0, 0.08);
            background: transparent;
            transition: background-color 0.2s ease;
        }

        .resizer-v:hover {
            background: rgba(78, 110, 242, 0.1);
        }

        .resizer-v.resizing {
            background: rgba(78, 110, 242, 0.2);
        }

        .resizer:hover {
            background: rgba(78, 110, 242, 0.1);
            border-color: rgba(78, 110, 242, 0.3);
        }

        .resizing {
            background: rgba(78, 110, 242, 0.15);
            border-color: rgba(78, 110, 242, 0.4);
        }

        /* 添加滚动条样式 */
        ::-webkit-scrollbar {
            width: 8px;
            height: 8px;
        }

        ::-webkit-scrollbar-track {
            background: #f1f1f1;
        }

        ::-webkit-scrollbar-thumb {
            background: #c1c1c1;
            border-radius: 4px;
        }

        ::-webkit-scrollbar-thumb:hover {
            background: #a8a8a8;
        }

        /* 拖动时的遮罩层 */
        .resize-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: transparent;
            display: none;
            z-index: 9999;
            cursor: inherit;
        }

        /* 添加可拖动面板的样式 */
        .drag-panel {
            position: absolute;
            top: 100px;
            left: 100px;
            background: white;
            border-radius: 4px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
            z-index: 10000;
            user-select: none;
            width: 260px
        }

        .panel-header {
            padding: 8px 10px;
            background: #f89406;
            color: white;
            cursor: move;
            border-radius: 4px 4px 0 0;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .panel-title {
            font-weight: bold;
            font-size: 14px;
        }

        .panel-toggle {
            cursor: pointer;
            padding: 2px 8px;
            background: rgba(0, 0, 0, 0.1);
            border-radius: 2px;
            font-size: 12px;
        }

        .panel-toggle:hover {
            background: rgba(0, 0, 0, 0.2);
        }

        .panel-content {
            padding: 10px;
            background: white;
            border-radius: 0 0 4px 4px;
            overflow: hidden;
            transition: height 0.3s ease;
            font-size: 14px;
            line-height: 1.4;
        }

        .panel-content h6 {
            margin: 0 0 8px 0;
            color: #666;
            font-size: 12px;
            font-weight: normal;
        }

        .panel-content h5 {
            margin: 12px 0 6px 0;
            color: #333;
            font-size: 13px;
            font-weight: bold;
        }

        .panel-content hr {
            margin: 8px 0;
            border: none;
            border-top: 1px solid #eee;
        }

        .sub-opt {
            display: flex;
            flex-wrap: wrap;
            gap: 4px;
            margin-bottom: 4px;
        }

        .sub-opt a {
            color: #4e6ef2;
            cursor: pointer;
            text-decoration: none;
            transition: all 0.2s ease;
            position: relative;
            padding: 1px 3px;
            border-radius: 2px;
            font-size: 12px;
        }

        .sub-opt a:hover {
            background-color: rgba(78, 110, 242, 0.1);
            color: #2440c8;
        }

        .sub-opt a:active {
            background-color: rgba(78, 110, 242, 0.2);
        }

        .sub-opt [lay-separator] {
            margin: 0 4px;
            color: #999;
        }

        .panel-content.collapsed {
            height: 0;
            padding: 0;
        }

        .drag-panel.collapsed {
            background: transparent;
            box-shadow: none;
        }

        .drag-panel.collapsed .panel-header {
            border-radius: 4px;
        }

        #apply {
            background-color: #16b777;
        }

        #delete {
            background-color: #ff5722;
        }

        .sub-container {
            margin: 0.3cm;
        }

        .p3 {
            margin: 0.3cm;
            display: none;
        }


        /* 自定义菜单样式 */
        /* 添加节点菜单样式 */
        .add-node-menu {
            position: fixed;
            background: white;
            border-radius: 4px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            padding: 4px 0;
            min-width: 120px;
            display: none;
            z-index: 10000;
            list-style: none;
            margin: 0;
        }

        .add-node-menu li {
            padding: 8px 16px;
            cursor: pointer;
            font-size: 14px;
            color: #333;
            transition: all 0.2s ease;
        }

        .add-node-menu li:hover {
            background-color: #f5f7fa;
            color: #4e6ef2;
        }

        /* 在 style 标签内添加菜单样式 */
        .context-menu {
            position: fixed;
            background: white;
            border-radius: 4px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
            padding: 4px 0;
            min-width: 120px;
            display: none;
            z-index: 10000;
            list-style: none;
            margin: 0;
        }

        .context-menu li {
            padding: 8px 16px;
            cursor: pointer;
            font-size: 13px;
            color: #333;
            transition: all 0.2s ease;
        }

        .context-menu li:hover {
            background-color: #f5f7fa;
            color: #4e6ef2;
        }

        #no-data {
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        #data-display-tb {
            width: 100%;
            height: 100%;
        }

        #data-display-tb th, #data-display-tb th * {
            cursor: pointer;
        }

        #ipt-xpath {
            width: 90%;
        }

        #select-ele:hover {
            cursor: pointer;
            background-color: #ececec;
        }

        #col-operation:hover {
            cursor: pointer;
            background-color: #ececec;
        }

        /* 后处理配置面板相关 */
        #reprocess-operate-background {
            width: 100%;
            height: 100%;
            background-color: rgb(255, 255, 255);
            display: flex;
        }

        #reprocess-operate {
            display: flex;
            width: 100%;
            height: 100%;
            background-color: rgb(255, 255, 255);
        }

        #left-div, #right-div {
            flex: 1;
            padding: 0.3cm;
            border: 1px solid #ccc;
        }

        #left-div {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }

        #add-step {
            cursor: pointer;
        }

        #list {
            list-style-type: none;
            padding: 0;
        }

        .list-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
            margin-bottom: 5px;
            cursor: pointer;
            height: 0.2cm;
        }

        .list-item:hover {
            background-color: #f0f0f0;
            cursor: default;
        }

        .delete-icon {
            cursor: pointer;
            color: red;
        }

        #right-div {
            background-color: #ffffff;
            position: relative;
            overflow: auto;
            flex: 2;
        }

        .panel {
            display: none;
            padding: 20px;
            border: 1px solid #ccc;
            border-radius: 5px;
            background-color: white;
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            z-index: 1;
        }

        .panel h2 {
            margin-top: 0;
        }

        .panel input,
        .panel button {
            margin-bottom: 10px;
            padding: 5px;
        }

        #div-list {
            overflow-y: auto;
        }

        #add-step {
            width: 2cm;
            height: 0.6cm;
            margin-left: 0;
        }

        #apply-reprocess, #yes {
            width: 1.2cm;
            height: 0.6cm;
            margin-left: 0;
            background-color: #16b777;
        }

        #cancel-reprocess, #no {
            width: 1.2cm;
            height: 0.6cm;
            margin-left: 0;
            background-color: #ff5722;
        }

        .layui-input {
            height: 0.7cm;
        }

        #origin-text, #match-text {
            height: 1.2cm;
            min-height: 0;
        }

        #yes, #no {
            margin-right: 10px;
        }

        #right-div div {
            margin-bottom: 3px;
        }

        .t1 {
            width: 80%;
            height: 35px;
            min-height: 35px;
            background-color: #f3f3f3;
            border: 4px solid #e6e6e6;
            border-radius: 8px;
            text-align: center;
            place-content: center;
        }

        .t2 {
            width: 80%;

            display: flex;
            flex-direction: column;
            align-items: center;

            border: 4px solid #e6e6e6;
            border-radius: 8px;
        }

        .t1:hover, .t2-1:hover {
            cursor: pointer;
        }

        .t2-1 {
            width: 100%;
            height: 25px;
            background-color: #f3f3f3;
            text-align: center;
            place-content: center;
        }

        .arrow {
            margin: 7px;
        }

        .arrow:hover {
            cursor: pointer;
        }

        .add-branch:hover {
            cursor: pointer;
        }

        .add-branch {
            margin-bottom: 20px;
        }
    </style>
</head>

<body>
<div class="resize-overlay"></div>

<div class="top-nav">
    <div class="nav-controls">
        <button class="nav-icon" id="backBtn" title="后退">
            <svg width="16" height="16" viewBox="0 0 16 16">
                <path fill="currentColor"
                      d="M6.7 8l3.8 3.8c.2.2.2.5 0 .7s-.5.2-.7 0l-4.1-4.1c-.2-.2-.2-.5 0-.7l4.1-4.1c.2-.2.5-.2.7 0s.2.5 0 .7L6.7 8z"/>
            </svg>
        </button>
        <button class="nav-icon" id="forwardBtn" title="前进">
            <svg width="16" height="16" viewBox="0 0 16 16">
                <path fill="currentColor"
                      d="M9.3 8L5.5 4.2c-.2-.2-.2-.5 0-.7s.5-.2.7 0l4.1 4.1c.2.2.2.5 0 .7l-4.1 4.1c-.2.2-.5.2-.7 0s-.2-.5 0-.7L9.3 8z"/>
            </svg>
        </button>
        <button class="nav-icon" id="reloadBtn" title="重新加载">
            <svg width="16" height="16" viewBox="0 0 16 16">
                <path fill="currentColor"
                      d="M13.6 2.4C12.2 1 10.2 0 8 0 3.6 0 0 3.6 0 8s3.6 8 8 8c3.7 0 6.8-2.5 7.7-6h-2.1c-.8 2.3-3 4-5.6 4-3.3 0-6-2.7-6-6s2.7-6 6-6c1.7 0 3.2.7 4.2 1.8L9 7h7V0l-2.4 2.4z"/>
            </svg>
        </button>
    </div>
    <input type="text" class="url-input" id="urlInput">
    <div class="nav-buttons">
        <button class="nav-button detail-btn" id="detailBtn">任务详情</button>
        <button class="nav-button save-btn" id="saveBtn">保存</button>
        <button class="nav-button capture-btn" id="captureBtn">采集</button>
        <button class="nav-button exit-btn" id="exitBtn">退出</button>
    </div>
</div>

<div class="main-content">
    <div class="center-content">
        <div class="webview-container">
            <webview id="myWebview" preload="embedded_page_preload.js" allowpopups></webview>
        </div>

        <div class="bottom-panel">
            <div class="resizer resizer-v" id="bottomResizer"></div>
            <!-- 工具栏 -->
            <div class="bottom-toolbar">
                <div class="preview-text">
                    <span>数据预览</span>
                    <strong>共 <span id="dataCount">0</span> 条</strong>
                </div>
                <div class="toolbar-icons">
                    <button class="toolbar-icon" id="add-col">
                        <img src="../../resources/add-col.svg">
                    </button>
                    <button class="toolbar-icon" id="clear-data">
                        <img src="../../resources/clear-data.svg">
                    </button>
                </div>

            </div>
            <!-- 数据内容区域 -->
            <div class="bottom-content">
                <!-- 这里将由JS代码填充表格内容 -->
                <div id="data-display-tb" style="display: none">
                    <table class="layui-hide" id="ID-table-demo-data" lay-filter="myTable"></table>

                </div>
                <div id="no-data">
                    <img src="../../resources/empty.svg">
                    <span>请点击数据提取节点进行数据预览</span>
                </div>
                <!--字段操作面板-->
                <div id="reprocess-operate-background" style="display: none">
                    <div id="reprocess-operate">
                        <div id="left-div">
                            <div id="div-button">
                                <button type="button" class="layui-btn layui-btn-xs layui-btn-normal" id="add-step">+
                                    添加步骤
                                </button>
                                <button type="button" class="layui-btn layui-btn-xs layui-btn-normal"
                                        id="apply-reprocess">确定
                                </button>
                                <button type="button" class="layui-btn layui-btn-xs layui-btn-normal"
                                        id="cancel-reprocess">取消
                                </button>
                            </div>

                            <div id="div-list">
                                <ul id="list"></ul>
                            </div>
                        </div>
                        <div id="right-div" class="layui-form">
                            <div class="p100 opt" style="display: none">
                                <span>正则表达式</span><br>
                                <input type="text" name="" placeholder="regexp..." class="layui-input" id="ipt-regexp">
                            </div>
                            <div class="p100 opt" style="display: none">
                                <span>原始文本<button type="button" class="layui-btn layui-btn-primary layui-btn-xs"
                                                      id="test-regexp">测试</button></span><br>
                                <textarea class="layui-textarea" rows="3"
                                          style="resize: none;overflow: auto;" id="origin-text"
                                          placeholder="请输入原始文本..."></textarea>
                            </div>
                            <div class="p100 opt" style="display: none">
                                <span>匹配结果</span><br>
                                <textarea class="layui-textarea" rows="3"
                                          style="resize: none;overflow: auto;" id="match-text"
                                          placeholder="匹配后结果..."></textarea>
                            </div>
                            <div class="p102 opt" style="display: none">
                                <span>前缀</span><br>
                                <input type="text" name="" placeholder="prefix..." class="layui-input" id="ipt-prefix">
                            </div>
                            <div class="p103 opt" style="display: none">
                                <span>后缀</span><br>
                                <input type="text" name="" placeholder="suffix..." class="layui-input" id="ipt-suffix">
                            </div>

                            <div class="p100 p102 p103 opt" style="display: none">
                                <button type="button" class="layui-btn layui-btn-xs layui-btn-normal" id="yes">确定
                                </button>
                                <button type="button" class="layui-btn layui-btn-xs layui-btn-normal" id="no">取消
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="right-panel">
        <div class="resizer resizer-h" id="rightResizer"></div>
        <div class="flow-container" id="flowContainer">
            <div class="flow-content" id="task-flow">
                <!-- 这里将由JS代码填充流程图 -->
            </div>
        </div>
        <div class="node-config" id="nodeConfig">
            <div class="resizer node-config-resizer" id="nodeConfigResizer"></div>
            <div class="node-config-content layui-form">
                <!-- 这里将由JS代码填充节点配置内容 -->

                <!--显示步骤名组件-通用组件-->
                <div class="sub-container">
                    <span>步骤名</span><br>
                    <input type="text" name="" placeholder="name..." class="layui-input" id="ipt-step-name">
                </div>
                <!--显示单个网址组件-->
                <div class="sub-container p3 optional" style="display: none">
                    <span style="margin-right: 20px">网址</span>
                    <input type="checkbox" name="AAA" id="use-loop-url"
                           lay-filter="use-loop-url"><span>基于外层循环</span><br>
                    <input type="text" name="" placeholder="url..." class="layui-input" id="ipt-page-url">
                </div>
                <!--显示单行xpath组件-->
                <div class="sub-container p4 p6 loop-paging optional" style="display: none">
                    <span style="margin-right: 20px">元素xpath</span>
                    <input type="checkbox" name="AAA" id="use-loop-xpath"
                           lay-filter="use-loop-xpath"><span>基于外层循环</span><br>
                    <div style="display: flex; flex-direction: row;align-items: center;">
                        <input type="text" name="" placeholder="xpath..." class="layui-input" id="ipt-xpath">
                        <img src="../../resources/pointer.svg" id="select-ele">
                    </div>
                    <button type="button" class="layui-btn layui-btn-xs" id="btn-test-xpath">测试</button>
                </div>
                <!--显示提取数据时数据类型组件-->
                <div class="sub-container p6 optional" style="display: none">
                    <span>数据类型</span><br>
                    <select name="quiz1" id="selector-dataType">
                        <option value="0">文本</option>
                        <option value="1">链接</option>
                        <option value="2">文本+链接</option>
                        <option value="10">NONE</option>
                    </select>
                </div>
                <!--显示循环类型组件-->
                <div class="sub-container p5 optional" style="display: none">
                    <span>循环类型</span><br>
                    <select id="selector-loopType" lay-filter="loopType">
                        <option value="2">循环元素列表</option>
                        <option value="1">循环网页</option>
                        <option value="3">循环单元素-点击</option>
                    </select>
                </div>
                <!--显示网址列表组件-->
                <div class="sub-container loop-url optional" style="display: none">
                    <span>网址列表</span><br>
                    <textarea name="" placeholder="例如:https://www.baidu.com/" class="layui-textarea" rows="8"
                              style="resize: none;overflow: auto;white-space: nowrap;" id="ta-url"></textarea>
                </div>
                <!--显示xpath列表组件-->
                <div class="sub-container loop-list optional" style="display: none">
                    <span>元素xpath</span><br>
                    <textarea name="" placeholder="例如://body/div[1]/div[3]/ul[1]/li" class="layui-textarea"
                              style="resize: none;overflow: auto;white-space: nowrap;" id="ta-xpath"></textarea>
                    <button type="button" class="layui-btn layui-btn-xs" id="btn-test-xpath-list">测试</button>
                </div>
                <!--显示循环次数-->
                <div class="sub-container p5 optional" style="display: none">
                    <input type="checkbox" name="AAA" id="ck-use-loop-times"
                           lay-filter="ck-use-loop-times"><span>执行循环次数</span><br>
                    <div class="layui-input-inline" id="loop-times" style="visibility: hidden;">
                        <input type="number" name="price_min" placeholder="" autocomplete="off"
                               class="layui-input" min="0" step="1"
                               lay-affix="number" value="0" id="ipt-loop-times">
                    </div>
                </div>
                <!--显示条件类型-->
                <div class="sub-container p8 optional" style="display: none">
                    <span>条件类型</span><br>
                    <select id="selector-conditionType" lay-filter="conditionType">
                        <option value="0">基于文本(正则表达式匹配)</option>
                        <option value="1">基于元素(xpath定位)</option>
                    </select>
                </div>
                <!--显示条件-->
                <div class="sub-container p8 optional" style="display: none">
                    <span>条件</span><br>
                    <input type="text" name="" placeholder="输入条件..." class="layui-input" id="condition-pattern">
                </div>
                <!-- 全局通用组件 -->
                <hr>
                <div class="sub-container">
                    <span>执行前等待(ms)</span><br>
                    <div class="layui-input-inline">
                        <input type="number" name="price_min" placeholder="" autocomplete="off"
                               class="layui-input" min="0" step="1" lay-affix="number" id="before-wait"
                               value="0">
                    </div>
                    <input type="checkbox" name="AAA" title="随机(1~5s)" id="random-wait">
                </div>
                <div class="p3" style="display: none !important;">
                    <span>超时时间(ms)</span><br>
                    <div class="layui-input-inline">
                        <input type="number" name="price_min" placeholder="" autocomplete="off"
                               class="layui-input" min="0" step="1" lay-affix="number" id="timeout"
                               value="0">
                    </div>
                </div>
                <div class="p3" style="display: none !important;">
                    <span>失败重试</span><br>
                    <span>次数</span>
                    <div class="layui-input-inline">
                        <input type="number" name="price_min" placeholder="" autocomplete="off"
                               class="layui-input" min="0" step="1" lay-affix="number" id="retry-times"
                               value="0">
                    </div>
                    <span>间隔(ms)</span>
                    <div class="layui-input-inline">
                        <input type="number" name="price_min" placeholder="" autocomplete="off"
                               class="layui-input" min="0" step="1" lay-affix="number" id="retry-interval"
                               value="0">
                    </div>
                </div>
                <hr>
                <div class="sub-container">
                    <button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="apply">应用
                    </button>
                    <button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="cancel">取消
                    </button>
                    <button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="delete">删除
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>

<div class="drag-panel">
    <div class="panel-header">
        <span class="panel-title">操作提示</span>
        <span class="panel-toggle">﹀</span>
    </div>
    <div class="panel-content">
        <h6 id="select-status">请通过鼠标选择网页内容</h6>
        <hr>
        <span class="sub-opt">
            <a id="select-all">选中全部</a>
            <span lay-separator>|</span>
            <a id="cancel-select">取消选中</a>
        </span>
        <h5>提取数据</h5>
        <span class="sub-opt">
            <a id="extract-text">提取文本</a>
            <span lay-separator>|</span>
            <a id="extract-link">提取链接</a>
            <span lay-separator>|</span>
            <a id="extract-link-text">提取文本+链接</a>
        </span>
        <h5>鼠标事件</h5>
        <span class="sub-opt">
            <a id="click-element">点击一次</a>
            <span lay-separator>|</span>
            <a id="click-element-loop">循环点击</a>
            <span lay-separator>|</span>
            <a id="click-each-element-loop">循环点击每一项</a>
        </span>
        <h5>输入编辑</h5>
        <span class="sub-opt">
            <a id="input-text">输入文本</a>
        </span>
    </div>
</div>
<!-- 添加列时弹出的菜单 -->
<ul class="add-node-menu" id="add-col-menu">
    <li id="50">提取网页URL</li>
    <li id="51">提取网页Title</li>
    <li id="52">添加提取时间</li>
</ul>
<!-- 添加列后处理时弹出的菜单 -->
<ul class="add-node-menu" id="col-reprocess">
    <li id="reprocess">后处理</li>
    <li>删除列</li>
</ul>
<!-- 添加节点时弹出的菜单 -->
<ul class="add-node-menu" id="add-node-menu">
    <li id="3">打开网页</li>
    <li id="4">点击元素</li>
    <li id="5">循环</li>
    <li id="6">提取数据</li>
    <li id="7">判断条件</li>
</ul>
<!-- 点击添加步骤时弹出的菜单 -->
<ul class="add-node-menu" id="step-list">
    <li data-action="regex-match" id="100">正则匹配</li>
    <li data-action="remove-empty-strings" id="101">去除空字符
    </li>
    <li data-action="add-prefix" id="102">添加前缀</li>
    <li data-action="add-suffix" id="103">添加后缀</li>
</ul>
<script>
    let isResizing = false;
    let currentResizer = null;
    let startX = 0;
    let startY = 0;
    let startWidth = 0;
    let startHeight = 0;
    // 遮罩层,用于下侧面板和右侧面板的拖动
    const $overlay = $('.resize-overlay');
    const $webview = $('webview');

    // 节点配置区域的拖拽逻辑
    let nodeConfigStartY = 0;
    let nodeConfigStartHeight = 0;

    // 拖动条鼠标按下事件
    $('.resizer').on('mousedown', function (e) {
        isResizing = true;
        currentResizer = $(this);

        if ($(this).hasClass('resizer-h')) {
            startX = e.clientX;
            startWidth = $('.right-panel').width();
            $overlay.css('cursor', 'ew-resize');
        } else if ($(this).hasClass('resizer-v')) {
            startY = e.clientY;
            startHeight = $('.bottom-panel').height();
            $overlay.css('cursor', 'ns-resize');
        } else if ($(this).hasClass('node-config-resizer')) {
            nodeConfigStartY = e.clientY;
            nodeConfigStartHeight = $('#nodeConfig').height();
            $overlay.css('cursor', 'ns-resize');
        }

        // 显示遮罩层
        $overlay.show();

        // 禁用 webview 的指针事件
        $webview.css('pointer-events', 'none');

        $(this).addClass('resizing');
        e.preventDefault();
        e.stopPropagation();
    });

    // 全局鼠标移动事件
    $overlay.on('mousemove', function (e) {
        if (!isResizing) return;
        e.preventDefault();

        if (currentResizer.hasClass('resizer-h')) {
            const containerWidth = $('.main-content').width();
            const dx = startX - e.clientX;
            const newWidth = startWidth + dx;
            if (newWidth >= 200 && newWidth <= containerWidth * 0.6) {
                $('.right-panel').css('flex', `0 0 ${newWidth}px`);
            }
            console.log(11);
        } else if (currentResizer.hasClass('resizer-v')) {
            const containerHeight = $('.center-content').height();
            const dy = startY - e.clientY;
            const newHeight = startHeight + dy;
            if (newHeight >= 100 && newHeight <= containerHeight * 0.8) {
                $('.bottom-panel').css('height', `${newHeight}px`);
            }
            console.log(22);
        } else if (currentResizer.hasClass('node-config-resizer')) {
            const dy = nodeConfigStartY - e.clientY;
            let newHeight = nodeConfigStartHeight + dy;
            const maxHeight = $('.right-panel').height() * 0.9;
            const minHeight = 100;

            // 限制高度范围
            newHeight = Math.max(minHeight, Math.min(newHeight, maxHeight));

            // 使用 flex-basis 来调整高度
            $('#nodeConfig').css('flex', `0 0 ${newHeight}px`);
        }
    });

    // 全局鼠标松开事件
    $overlay.on('mouseup', function (e) {
        if (isResizing) {
            isResizing = false;
            currentResizer.removeClass('resizing');
            currentResizer = null;
            startX = 0;
            startY = 0;
            startWidth = 0;
            startHeight = 0;

            // 隐藏遮罩层
            $overlay.hide();

            // 重新启用 iframe 的指针事件
            $webview.css('pointer-events', 'auto');
        }
    });

    // 确保在页面失去焦点时也能正确处理
    $(window).on('blur', function () {
        if (isResizing) {
            $overlay.trigger('mouseup');
        }
    });


    // 显示节点配置的函数
    function showNodeConfig() {
        $('#nodeConfig').show();
    }

    // 隐藏节点配置的函数
    function hideNodeConfig() {
        $('#nodeConfig').hide();
    }


    $(document).ready(function () {
        const $panel = $('.drag-panel');
        const $header = $('.panel-header');
        const $toggle = $('.panel-toggle');
        const $content = $('.panel-content');
        let isDragging = false;
        let startX, startY, initialX, initialY;

        // 处理面板拖动
        $header.on('mousedown', function (e) {
            isDragging = true;
            startX = e.clientX;
            startY = e.clientY;
            initialX = $panel.offset().left;
            initialY = $panel.offset().top;

            // 添加临时事件处理器
            $(document).on('mousemove.panel', function (e) {
                if (isDragging) {
                    const dx = e.clientX - startX;
                    const dy = e.clientY - startY;

                    // 计算新位置
                    let newLeft = initialX + dx;
                    let newTop = initialY + dy;

                    // 获取视口尺寸
                    const viewportWidth = $(window).width();
                    const viewportHeight = $(window).height();

                    // 获取面板尺寸
                    const panelWidth = $panel.outerWidth();
                    const panelHeight = $panel.outerHeight();

                    // 确保面板不会超出视口边界
                    newLeft = Math.max(0, Math.min(newLeft, viewportWidth - panelWidth));
                    newTop = Math.max(0, Math.min(newTop, viewportHeight - panelHeight));

                    // 应用新位置
                    $panel.css({
                        left: newLeft + 'px',
                        top: newTop + 'px'
                    });
                }
            });

            $(document).on('mouseup.panel', function () {
                isDragging = false;
                $(document).off('mousemove.panel mouseup.panel');
            });
        });

        // 处理面板展开/收起
        $toggle.on('click', function () {
            $content.toggleClass('collapsed');
            $panel.toggleClass('collapsed');
            $(this).text(function (_, text) {
                return text === '﹀' ? '︿' : '﹀';
            });

            // 展开/收起后检查位置
            constrainPanel();
        });

        // 确保面板不会被拖出视口
        function constrainPanel() {
            const viewportWidth = $(window).width();
            const viewportHeight = $(window).height();
            const panelWidth = $panel.outerWidth();
            const panelHeight = $panel.outerHeight();

            let left = parseInt($panel.css('left'));
            let top = parseInt($panel.css('top'));

            // 确保面板完全在视口内
            left = Math.max(0, Math.min(left, viewportWidth - panelWidth));
            top = Math.max(0, Math.min(top, viewportHeight - panelHeight));

            $panel.css({
                left: left + 'px',
                top: top + 'px'
            });
        }

        // 监听窗口大小变化
        $(window).on('resize', constrainPanel);

        // 初始化时确保面板在可见区域内
        constrainPanel();

        $(document).on('click', function (event) {
            const className = $(event.target).attr('class');
            if (className !== 'arrow') {
                $('#add-node-menu').css('display', 'none');
            }
            if (!(event.target.id === 'add-col' || event.target.parentElement.id === 'add-col')) {
                $('#add-col-menu').css('display', 'none');
            }
            if (event.target.id !== 'col-operation') {
                $('#col-reprocess').css('display', 'none')
            }
            if (event.target.id !== 'add-step') {
                $('#step-list').css('display', 'none')
            }

        });

        layui.form.on('checkbox(ck-use-loop-times)', (data) => {
            if (data.elem.checked) {
                $('#loop-times').css('visibility', 'visible')
            } else {
                $('#loop-times').css('visibility', 'hidden')
            }
        })

        layui.form.on('checkbox(use-loop-xpath)', (data) => {
            const iptXpath = $('#ipt-xpath')
            if (data.elem.checked) {
                iptXpath.val('使用循环中元素')
                iptXpath.prop('readonly', true)
            } else {
                iptXpath.val('')
                iptXpath.removeAttr('readonly')
            }
        })

        layui.form.on('checkbox(use-loop-url)', (data) => {
            const iptXpath = $('#ipt-page-url')
            if (data.elem.checked) {
                iptXpath.val('使用循环中URL')
                iptXpath.prop('readonly', true)
            } else {
                iptXpath.val('')
                iptXpath.removeAttr('readonly')
            }
        })

        layui.form.on('select(loopType)', (data) => {
            switch (data.value) {
                case '1':
                    $('.loop-url').css('display', 'block')
                    $('#ta-url').val('')
                    $('.loop-list').css('display', 'none')
                    $('.loop-paging').css('display', 'none')
                    break;
                case '2':
                    $('.loop-url').css('display', 'none')
                    $('.loop-list').css('display', 'block')
                    $('#ta-xpath').val('')
                    $('.loop-paging').css('display', 'none')
                    break;
                case '3':
                    $('.loop-url').css('display', 'none')
                    $('.loop-list').css('display', 'none')
                    $('.loop-paging').css('display', 'block')
                    $('#ipt-xpath').val('')
                    break;
            }
        })
    });


</script>
<script src="taskflow_generate.js"></script>
<script src="crawler_edit_render.js"></script>
</body>

</html>